# 1、搭建好pyenv环境，理解并写出local、global、shell3种方式区别，安装部署完成jupyter并运行。

# global

"""如果使用此命令，所有受到pyenv控制的窗口单元都受到了影响，特别要注意权限问题，可能会影响之前的系统"""

# shell

"""只会影响当前会话"""

# local

"""只影响所在文件夹"""

# 2、打印出100以内的斐波那契数列，使用2种方法实现

# 方法1,使用fn = f(n-1) + f(n-2) 迭代的方式实现
def fib(n):
    """斐波那契数列使用公式求第n个值"""
    if n <= 2:
        return 1
    return fib(n-1)+fib(n-2)

for x in range(1,101):
    print(fib(x), end='\n' if x % 10==0 else ' ')

# 以上方法计算太慢，消耗的资源太多
# 采用functools.lru_cache提升计算速度
from functools import lru_cache


@lru_cache()
def fib_better(n):
    if n == 2 or n == 1:
        return 1
    return fib_better(n - 1) + fib_better(n - 2)


for x in range(1, 102):
    print(fib_better(x), end='\n' if x % 10 == 0 else ' ')


# 方法2 使用 a,b = b , a+b ，的方式实现

def fib_exchange(n):
    a = 0
    b = 1
    while n > 0:
        a, b = b, a + b
        print(a)
        n -= 1


fib_exchange(101)

# 3、使用 Python 实现随机生成 200 无重复激活码（或者优惠券），字符串长度大于5以上
import random

alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'


# 方法1，使用random模块实现随机选取，放在set集合中查看是否重复

def create_cdk(n):
    s = set()
    for i in range(n):
        lst = []
        for x in range(random.randint(5, 10)):
            lst.append(random.choice(alphabet))
        s.add(''.join(lst))  # 这里实现不了去重效果，当有重复的字符串出现时（虽然几率很小），在s里只会出现一次。但是s的长度会小于200.
    return s


x = create_cdk(200)
print(len(x))
print(x)



# 方法2.使用itertools 模块实现随机取,生成固定长度的优惠券

import itertools

def create_ckd(n: int, length: int = 6) -> set:
    """
    :param n: 优惠券个数
    :param length: 优惠券长度
    :return:
    """
    s = set()
    g_ckd = (''.join(x) for x in itertools.product(alphabet, repeat=length))
    for i in range(n):
        s.add(next(g_ckd))
    return s


print(create_ckd(30, 5))

# 这个方法的结果高度相似，且不区分大小写。在实际的生产应用中要注意。